#include<iostream>
#include<pthread.h>
#include<unistd.h>
#include<cstdlib>
#include<cerrno>
#include<string.h>

using namespace std;

//线程谁先运行与调度器相关
//线程一旦异常会导致整个进程退出
int g_val=0;
//__therad int g_val=0;
//线程局部存储,使得每一个线程都有一个这样的局部变量
void* threadRoutine(void* args)
{
    //线程分离，当主线程不想等待你的时候我就可以将你分离
    //分离等待绝对不能同时进行
    pthread_detach(pthread_self());
    while(true)
    {
        cout<<(char*)args<<":"<<g_val<<"&:"<<&g_val<<endl;
        g_val++;
        sleep(2);
        break;
    }
    pthread_exit((void*)-1);
    // sleep(5);
    // //之后的程序被整个替换
    // //execl("/bin/ls","ls","-l",nullptr);
    // while(true)
    // {
    //     cout<<(char*)args<<":"<<&g_val<<"&:"<<&g_val<<endl;
    //     g_val++;
    //     sleep(1);
    // }
    // int i=0;
    // int *data=new int[10];
    // while(true)
    // {
    //     cout<<(char*)args<<"running"<<endl;
    //     sleep(1);
    //     data[i]=i;
    //     if(++i==5)
    //     {
    //         break;
    //     }
    //     //线程异常
    //     // int a=100;
    //     // a/=0;
    // }
    // cout<<"new therad quit"<<endl;
    //谁在等我这个返回值就给谁，一般都是返回给主线程
    //把10作为一个地址数据
    //return (void*)10;
    //将这里的data作为一个地址数据

    //exit(10)这代表着终止进程，即便是线程当中调用整个进程也会退出
    
    //pthread_exit()这里代表着线程终止
    //这个时候就可以顺利地拿到线程的退出码
    //pthread_exit((void*)11);
    //return (void*)data;
    
}

int main()
{
    //pthread_detatch 主线程不再等待，你从线程把事情办好就可以，你做的怎么样我也不关心，这样子效率更高
    //这个时候就会有两个线程在这里运行
    //void* ret=nullptr;
    int* ret=nullptr;
    //linux平台下指针大小为8字节
    //cout<<sizeof(ret)<<endl;
    pthread_t tid;
    //这里的参数类型是void**所以这里接受void*参数
    pthread_create(&tid,nullptr,threadRoutine,\
    (void*)"thread 1");

    // while(true)
    // {
    //     cout<<":"<<&g_val<<"&:"<<&g_val<<endl;
    //     sleep(1);
    // }

    int count=0;
    while(true)
    {
        cout<<"新线程: "<<"running..."<<endl;
        sleep(1);
        count++;
        if(count>=5)
        break;
    }
    int n=pthread_join(tid,nullptr);
    cout<<"n:"<<n<<strerror(n)<<endl;
    //即便新线程是一个死循环
    //线程取消的时候join（等待）的时候退出码是-1
    // pthread_cancel(tid);
    // cout<<"pthread cancle:"<<tid<<endl;

    //默认会阻塞等待新线程
    //这里的ret返回等待线程的返回结果
    //线程等待函数，会根据线程ID自动返回等待线程的返回结果
    pthread_join(tid,(void**)&ret);
    //pthread_join(tid,nullptr);
    
    //cout<<"main thread wait other thread"<<endl;
    //因为这里涉及到8个字节所以需要强制转成长整型数据
    //cout<<"退出码:"<<(long long)ret<<endl;

    cout<<"退出码："<<(long long)ret<<endl;

    // for(int i=0;i<5;i++)
    // {
    //     cout<<ret[i]<<endl;
    // }
    //线程在创建并且执行的时候线程也是需要等待的
    //如果主线程不等待将会引发线程的僵尸问题
    // while(true)
    // {
    //     cout<<"main 线程"<<"running"<<endl;
    //     sleep(1);
    // }

    return 0;
}